package com.example.zxing_qrcode_demo1;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

/**
 * @description
	简单实现 文本输入的 二维码创建，读取。
 * @author chendt
 * @date 2013-4-22
 * @Version 1.0
 */
public class MainActivity extends Activity implements OnClickListener {
	private static final int WHITE = 0xFFFFFFFF;
	private static final int BLACK = 0xFF000000; 
	
//	private static final int WHITE = 0xFF000000;//2.1 core.jar 无法实现，黑白颠倒的解码
//	private static final int BLACK = 0xFFFFFFFF;
	private ImageView qrView;
	private EditText inputText;
	private Button createQRBtn,decodeQRBtn;
	private Map<EncodeHintType, Object> hints;
	private Map<DecodeHintType, Object> decodeHints;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        qrView = (ImageView) findViewById(R.id.qr_code_view);
        inputText = (EditText) findViewById(R.id.qr_info_edit);
        createQRBtn = (Button) findViewById(R.id.create_qrcode_view);
        decodeQRBtn = (Button) findViewById(R.id.decode_qrcode_view);
        decodeQRBtn.setOnClickListener(this);
        createQRBtn.setOnClickListener(this);
        hints = setEncodeHintType();
    }

    /**
     * QR编码
     * @param message
     * @param hints
     * @return
     */
    private BitMatrix Encode(String message,Map<EncodeHintType,Object> hints) {
    	BitMatrix bitMatrix = null;
    	try {
    		bitMatrix  = new MultiFormatWriter().encode(message, BarcodeFormat.QR_CODE, 200, 200, hints);
		} catch (WriterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bitMatrix;
	}

	private Map<EncodeHintType, Object> setEncodeHintType() {
    	Map<EncodeHintType,Object> hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//        message = convertToUTF8(message);
        return hints;
	}
	
	/**
	 * 解码配置
	 * 配置需要解码的图片格式为二维码，字符集编码为UTF-8
	 * @return
	 */
	private Map<DecodeHintType, Object> setDecodeHintType(){
		Map<DecodeHintType,Object> hints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);
		Collection<BarcodeFormat> decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
		decodeFormats.addAll(EnumSet.of(BarcodeFormat.QR_CODE));
		hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
		hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
		return hints;
	}
	
	/**
	 * 生成二维码图
	 * @param bitMatrix
	 * @return
	 */
	private Bitmap toBitmap(BitMatrix bitMatrix) {
	    int width = bitMatrix.getWidth();
	    int height = bitMatrix.getHeight();
	    int[] pixels = new int[width * height];
	    for (int y = 0; y < height; y++) {
	      int offset = y * width;
	      for (int x = 0; x < width; x++) {
	        pixels[offset + x] = bitMatrix.get(x, y) ? BLACK : WHITE;
	      }
	    }
	    
	    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
	    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
	    return bitmap;
	}
	
	/**
	 * 将生成的二维码 对象，转换为BinaryBitmap 
	 * @param drawable
	 * @return
	 * @throws IOException
	 */
	private BinaryBitmap loadImage(Drawable drawable) throws IOException {
	    Bitmap bitmap = drawableToBitmap(drawable);
	    
	    int lWidth = bitmap.getWidth();
	    int lHeight = bitmap.getHeight();
	    int[] lPixels = new int[lWidth * lHeight];
	    bitmap.getPixels(lPixels, 0, lWidth, 0, 0, lWidth, lHeight);
	    return new BinaryBitmap(new HybridBinarizer(new RGBLuminanceSource(lWidth, lHeight, lPixels)));
	}
	
	private	Result decode(Drawable drawable){
		Result lResult = null;
		try {
			lResult = new MultiFormatReader().decode(loadImage(drawable), decodeHints);
		} catch (NotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return lResult;
	}
	
	/**
	 * drawable --> bitmap
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawableToBitmap(Drawable drawable) {
		BitmapDrawable bd = (BitmapDrawable) drawable;
		Bitmap bm = bd.getBitmap();
		return bm;
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.create_qrcode_view:
			if (TextUtils.isEmpty(inputText.getText().toString())) {
				Toast.makeText(MainActivity.this, "无文本，请输入", Toast.LENGTH_SHORT).show();
				return;
			}
			String input = null;
			try {
				input = String.valueOf(inputText.getText().toString().getBytes("UTF-8"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Bitmap bm =toBitmap(Encode(input, hints));
			qrView.setImageBitmap(bm);
			
			break;
		case R.id.decode_qrcode_view:
			if (qrView.getDrawable()==null) {
				Toast.makeText(MainActivity.this, "无图，请创建", Toast.LENGTH_SHORT).show();
				return;
			}
			setDecodeHintType();
			Result result = decode(qrView.getDrawable());
			Toast.makeText(MainActivity.this, "解码文本为:"+result.getText().toString(), Toast.LENGTH_LONG).show();
			break;
		default:
			break;
		}
	}
}
